package com.mingqijia.gassafety.job.job.mbp;
import java.util.*;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mingqijia.gassafety.db.constant.DtuConstant;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.mapper.AppealLogMapper;
import com.mingqijia.gassafety.db.mapper.DtuMapper;
import com.mingqijia.gassafety.db.mapper.WorkOrderCancelRecordMapper;
import com.mingqijia.gassafety.job.request.mbp.DetailOrderRequest;
import com.mingqijia.gassafety.job.service.*;
import com.mingqijia.gassafety.job.service.asst.AsstService;
import com.mingqijia.gassafety.job.service.mbp.TcisService;
import com.mingqijia.gassafety.shared.config.PositionType;
import com.mingqijia.gassafety.shared.constant.AppealStateEnum;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.MbpConst;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

import static com.mingqijia.gassafety.shared.constant.Constants.IS_DELETED_FALSE;

/**
 * @program: gassafety
 * @description: mbp 工单状态
 * @author: Mr.Wang
 * @create: 2022-11-17 13:58
 **/
@Component
@Slf4j
public class WorkOrderJob {

    @Autowired
    WorkOrderHistoryService workOrderHistoryService;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    TcisService tcisService;
    @Autowired
    MbpWorkOrderService mbpWorkOrderService;

    @Autowired
    HistoryAlarmService historyAlarmService;
    @Autowired
    HistoryBrokenService historyBrokenService;

    @Autowired
    AppealLogService appealLogService;
    @Autowired
    EquipmentService equipmentService;

    @Autowired
    AppealLogMapper appealLogMapper;

    @Autowired
    DtuMapper dMapper;
    
    @Autowired
    ConsumerLocationService consumerLocationService;

    @Autowired
    AsstService asstService;

    @Resource
    WorkOrderCancelRecordMapper workOrderCancelRecordMapper;

    @Resource
    WorkOrderHandleService workOrderHandleService;

//    @Scheduled(cron = "${gassafety.mbp.job.workOrderStatus}")
    @XxlJob("workOrderStatus")
    public ReturnT<String> workOrderStatus(String param) {
        XxlJobLogger.log("XXLJOB-workOrderStatus start...param: {}", param);
        try {
            log.info("workOrderStatus ---- start:");
            //查询 工单状态,并更新
            QueryWrapper<WorkOrderHistory> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().ne(WorkOrderHistory::getOrderNo, "") //工单主键
                    .eq(WorkOrderHistory::getOrderType, 1) //安装单
                    .eq(WorkOrderHistory::getHandleStatus, 0)  // 进行中
                    .in(WorkOrderHistory::getFromSystem, Arrays.asList(0, 2))
                    .in(WorkOrderHistory::getWorkSystem, Arrays.asList(1, 2))
                    .eq(WorkOrderHistory::getIsDeleted, Constants.IS_DELETED_FALSE);
            List<WorkOrderHistory> list = workOrderHistoryService.list(queryWrapper);
            log.info("workOrderStatus-list:{}",JSONObject.toJSONString(list));
            //遍历未完成工单
            for (WorkOrderHistory history : list) {

                WorkOrderHistory workOrder = new WorkOrderHistory();
                workOrder.setId(history.getId());
                workOrder.setCompleteTime(new Date());
                workOrder.setOrderChannel(history.getOrderChannel());
                workOrder.setDeviceId(history.getDeviceId());
                workOrder.setSpId(history.getSpId());
                workOrder.setCreatedAt(history.getCreatedAt());
                try {
                    log.info("workOrderStatus-appealIntallRecord:{}", JSONObject.toJSONString(workOrder));
                    //处理安装期间发生的报警、故障记录
                    appealIntallRecord(workOrder);
                } catch (Exception e) {
                    log.info("处理安装过程中的报警、安装记录报错：{}",e.getMessage());
                }
                JSONArray orderList;
                Integer code;
                if (2 == history.getWorkSystem()) {
                    String targetSpId = consumerService.getConsumerRelateSpId(history.getConsumerId(), history.getSpId());
                    Map<String, Object> response = asstService.queryOrderInfo(history.getOrderNo(), targetSpId);
                    orderList = JSONArray.parseArray(JSON.toJSONString(response.get("data")));
                    code = (Integer)response.get("code");
                } else {
                    DetailOrderRequest request = new DetailOrderRequest();
                    request.setUserid(history.getSubsCode());
                    request.setWorkpkid(history.getOrderNo());
                    Map<String, Object> map = new HashMap<>();
                    map.put("body", request);
                    log.info("调用1032-工单详情查询");
                    Map<String, Object> response = tcisService.tcisRequest(map, 4, null, history.getSpId(),history.getSubsCode());
                    orderList = JSONArray.parseArray(JSON.toJSONString(response.get("data")));
                    code = (Integer) response.get("code");
                }

                if (code.equals(0) && orderList.size() > 0) {
                    //更新工单状态,
                    for (int i = 0; i < orderList.size(); i++) {
                        JSONObject order = orderList.getJSONObject(i);
                        log.info("workOrderStatus-order:{}", JSONObject.toJSONString(order));
                        //工单完成
                        if (MbpConst.WORK_STATE_FINISH.equals(order.getString("state"))) {
                            //更新工单状态
                            WorkOrderHistory workOrderHistory = new WorkOrderHistory();
                            workOrderHistory.setId(history.getId());
                            workOrderHistory.setHandleStatus(1);
                            workOrderHistory.setCompleteTime(order.getDate("finishtime"));
                            workOrderHistory.setDeviceId(history.getDeviceId());
                            workOrderHistory.setSpId(history.getSpId());
                            workOrderHistoryService.updateById(workOrderHistory);
                            workOrderHistory.setCreatedAt(history.getCreatedAt());
                            String installposition = order.getString("installposition");
                            String position = StringUtils.isEmpty(installposition) ? "" : PositionType.parse(Integer.parseInt(installposition)).getName();
                            log.info("workOrderStatus-position:{},{},{}", position, installposition, history.getDeviceId());
                            Date completeTime = workOrderHistory.getCompleteTime();
                            String format = DateUtil.format(completeTime, "yyyy-MM-dd");
                            if(org.apache.commons.lang.StringUtils.isNotEmpty(history.getDeviceId()) &&
                                    history.getDeviceId().length() >= DtuConstant.IMEI_MIN_LENGTH) {
                                equipmentService.updatePosition(position,history.getDeviceId(),format);
                            }
                            if (history.getWorkSystem() == 2 && history.getConsumerId() > 0) {
                                LambdaUpdateWrapper<Consumer> consumerWrapper = new LambdaUpdateWrapper<>();
                                consumerWrapper.or().eq(Consumer::getId, history.getConsumerId())
                                        .set(Consumer::getStatus, 0);
                                consumerService.update(consumerWrapper);
                            } else {
                                consumerService.updateStatusByCode(history.getSubsCode());
                                //根据pkid 查询对应imei号, 进行设备绑定
                                if (history.getFromSystem() != 2) mbpWorkOrderService.queryAlarmAppliance(history);
                            }
                        } else if (MbpConst.WORK_STATE_END.equals(order.getString("state"))) {
                            WorkOrderHistory workOrderHistory = new WorkOrderHistory();
                            workOrderHistory.setId(history.getId());
                            workOrderHistory.setHandleStatus(1);
                            workOrderHistory.setReason("工单被终止");
                            workOrderHistoryService.updateById(workOrderHistory);
                            if (history.getWorkSystem() == 2 && history.getConsumerId() > 0) {
                                LambdaUpdateWrapper<Consumer> consumerWrapper = new LambdaUpdateWrapper<>();
                                consumerWrapper.or().eq(Consumer::getId, history.getConsumerId())
                                        .set(Consumer::getStatus, 0);
                                consumerService.update(consumerWrapper);
                            } else {
                                consumerService.updateStatusByCode(history.getSubsCode());
                                LambdaUpdateWrapper<Consumer> updateWrapper = new LambdaUpdateWrapper<>();
                                updateWrapper.or().eq(Consumer::getSubsCode,history.getSubsCode())
                                        .eq(Consumer::getSource,1)
                                        .set(Consumer::getIsDeleted,1);
                                consumerService.update(updateWrapper);
                                // update by wangwei for 11402
                                if(org.apache.commons.lang.StringUtils.isNotEmpty(history.getDeviceId()) &&
                                        history.getDeviceId().length() >= DtuConstant.IMEI_MIN_LENGTH) {
                                    LambdaUpdateWrapper<Dtu> lqw = new LambdaUpdateWrapper<>();
                                    lqw.likeRight(Dtu::getIMEI,history.getDeviceId())
                                            .eq(Dtu::getIsDeleted, IS_DELETED_FALSE)
                                            .set(Dtu::getConsumerId, 0)
                                            .set(Dtu::getSectorType, Constants.BLANK)
                                            .set(Dtu::getInstallationPosition,null)
                                            .set(Dtu::getInstallationAddress,null)
                                            .set(Dtu::getPositionLat,0.0)
                                            .set(Dtu::getPositionLon,0.0)
                                            .set(Dtu::getSource,0);
                                    equipmentService.update(lqw);
                                } else {
                                    log.warn("工单:{} 不符合规则无法更新", JSONObject.toJSONString(history));
                                }
                                consumerLocationService.updateConsumerLocationDeviceNumBySubsCode(history.getSubsCode());
                            }
                        }
                    }
                } else {
                    log.info("工单:{} 查询1032失败或未查询到工单", history.getOrderNo());

                }
            }
        } catch (Exception e) {
            log.info("workOrderStatus-error:{}", e);
        }
        XxlJobLogger.log("XXLJOB-workOrderStatus end...");
        return ReturnT.SUCCESS;
    }

    @XxlJob("cancelWorkOrder")
    public ReturnT<String> cancelWorkOrder(String param) {
        XxlJobLogger.log("XXLJOB-cancelWorkOrder start...param: {}", param);
        try {
            log.info("cancelWorkOrder ---- start:");
            List<WorkOrderCancelRecord> workOrderCancelRecordList = workOrderCancelRecordMapper.getFailedCancelRecord();
            log.info("cancelWorkOrder ---- 带执行取消工单记录:{}",JSONObject.toJSONString(workOrderCancelRecordList));
            for (WorkOrderCancelRecord workOrderCancelRecord : workOrderCancelRecordList) {
                workOrderHandleService.cancelOrder(workOrderCancelRecord);
            }
        }catch (Exception e){
            log.info("cancelWorkOrder-error:{}", e);
        }
        XxlJobLogger.log("XXLJOB-cancelWorkOrder end...");
        return ReturnT.SUCCESS;
    }


    private void appealIntallRecord(WorkOrderHistory installWorkOrder) {
        log.info("appealIntallRecord-installWorkOrder:{}",JSONObject.toJSON(installWorkOrder));
        if (installWorkOrder.getCompleteTime() == null||installWorkOrder.getOrderChannel()==0) {
            return;
        }
        LambdaUpdateWrapper<HistoryAlarm> alarmlqw = new LambdaUpdateWrapper<>();
        alarmlqw.like(HistoryAlarm::getIMEI, installWorkOrder.getDeviceId()).eq(HistoryAlarm::getSpId, installWorkOrder.getSpId())
                .between(HistoryAlarm::getCreatedAt, installWorkOrder.getCreatedAt(), installWorkOrder.getCompleteTime())
                .eq(HistoryAlarm::getIsDeleted, Constants.IS_DELETED_FALSE);
        List<HistoryAlarm> historyAlarms = historyAlarmService.list(alarmlqw);
        log.info("appealIntallRecord-historyAlarms:{}",JSONObject.toJSON(historyAlarms));
        if (!CollectionUtils.isEmpty(historyAlarms)) {
            List<AppealLog> appealLogs = new ArrayList<>();
            for (HistoryAlarm historyAlarm : historyAlarms) {
                LambdaQueryWrapper<AppealLog> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.or().eq(AppealLog::getIsDeleted,0).eq(AppealLog::getAlarmBrokenId,historyAlarm.getId());
                List<AppealLog> appeals = appealLogMapper.selectList(queryWrapper);
                log.info("appealIntallRecord-appeals:{}",JSONObject.toJSON(appeals));
                if(!CollectionUtils.isEmpty(appeals)){
                    continue;
                }
                AppealLog appealLog = new AppealLog();
                appealLog.setAppealType(0);
                appealLog.setAlarmBrokenId(historyAlarm.getId());
                appealLog.setAppealStatus(AppealStateEnum.HANDLED_INSTALL.getCode());
                appealLog.setUserName("安装调试");
                appealLog.setUserAccount("");
                appealLog.setIsDeleted(false);
                appealLog.setSpId(historyAlarm.getSpId());
                appealLogs.add(appealLog);
            }
            appealLogService.saveBatch(appealLogs);
            for (AppealLog appealLog : appealLogs) {
                // 更新报警信息记录主表
                LambdaUpdateWrapper<HistoryAlarm> historyAlarmWrapper = new LambdaUpdateWrapper<>();
                historyAlarmWrapper.eq(HistoryAlarm::getId,appealLog.getAlarmBrokenId()).eq(HistoryAlarm::getIsDeleted,0);
                HistoryAlarm historyAlarmLog = new HistoryAlarm();
                historyAlarmLog.setWorkorderId(appealLog.getWorkorderId() == null ? 0L : appealLog.getWorkorderId());
                historyAlarmLog.setAppealStatus(appealLog.getAppealStatus());
                historyAlarmLog.setAppealResult(appealLog.getAppealResult());
                historyAlarmLog.setUserName(appealLog.getUserName());
                historyAlarmLog.setUserAccount(appealLog.getUserAccount());
                historyAlarmLog.setAppealTime(appealLog.getCreatedAt());
                boolean historyAlarmResult = historyAlarmService.update(historyAlarmLog,historyAlarmWrapper);
                log.info("工单处理完成，更新报警器设备报警记录,结果：{}，内容：{}",historyAlarmResult,historyAlarmLog.toString());
            }
        }

        LambdaUpdateWrapper<HistoryBroken> brokenlqw = new LambdaUpdateWrapper<>();
        brokenlqw.like(HistoryBroken::getIMEI, installWorkOrder.getDeviceId()).eq(HistoryBroken::getSpId, installWorkOrder.getSpId())
                .between(HistoryBroken::getCreatedAt, installWorkOrder.getCreatedAt(), installWorkOrder.getCompleteTime())
                .eq(HistoryBroken::getIsDeleted, Constants.IS_DELETED_FALSE);
        List<HistoryBroken> brokens = historyBrokenService.list(brokenlqw);
        log.info("appealIntallRecord-brokens:{}",JSONObject.toJSON(brokens));
        if (!CollectionUtils.isEmpty(brokens)) {
            List<AppealLog> appealLogs = new ArrayList<>();
            for (HistoryBroken historyBroken : brokens) {
                LambdaQueryWrapper<AppealLog> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.or().eq(AppealLog::getIsDeleted,0).eq(AppealLog::getAlarmBrokenId,historyBroken.getId());
                List<AppealLog> appeals = appealLogMapper.selectList(queryWrapper);
                log.info("appealIntallRecord-appeals:{}",JSONObject.toJSON(appeals));
                if(!CollectionUtils.isEmpty(appeals)){
                    continue;
                }
                AppealLog appealLog = new AppealLog();
                appealLog.setAppealType(1);
                appealLog.setAlarmBrokenId(historyBroken.getId());
                appealLog.setAppealStatus(AppealStateEnum.HANDLED_INSTALL.getCode());
                appealLog.setUserName("安装调试");
                appealLog.setUserAccount("");
                appealLog.setIsDeleted(false);
                appealLog.setSpId(historyBroken.getSpId());
                appealLogs.add(appealLog);
            }
            appealLogService.saveBatch(appealLogs);
            for (AppealLog appealLog : appealLogs) {
                // 更新故障信息记录主表
                LambdaUpdateWrapper<HistoryBroken> historyBrokenWrapper = new LambdaUpdateWrapper<>();
                historyBrokenWrapper.eq(HistoryBroken::getId,appealLog.getAlarmBrokenId()).eq(HistoryBroken::getIsDeleted,0);
                HistoryBroken historyBrokenLog = new HistoryBroken();
                historyBrokenLog.setWorkorderId(appealLog.getWorkorderId() == null ? 0L : appealLog.getWorkorderId());
                historyBrokenLog.setAppealStatus(appealLog.getAppealStatus());
                historyBrokenLog.setAppealResult(appealLog.getAppealResult());
                historyBrokenLog.setUserName(appealLog.getUserName());
                historyBrokenLog.setUserAccount(appealLog.getUserAccount());
                historyBrokenLog.setAppealTime(appealLog.getCreatedAt());
                boolean historyBrokenResult = historyBrokenService.update(historyBrokenLog,historyBrokenWrapper);
                log.info("工单处理完成，更新报警器设备故障记录,结果：{}，内容：{}",historyBrokenResult,historyBrokenLog.toString());
            }
        }

    }


}
